from flask_restful import Resource
from flask import current_app,request,g
from comment.utils.sms_send import send_code

from comment.modules.user import User
from comment.modules.account import Account
import json

from comment.utils.Financial_Redis import fr

from financial.resources.user  import constants
from flask_restful.reqparse import RequestParser
from comment.modules import db
from comment.utils.tokens_pyjwt import generate_tokens,verity_tokens
from comment.utils.decorators import login_required
class Login(Resource):
    '''
    登录
    '''
    def post(self):
        rp = RequestParser()
        rp.add_argument('username', required=True)
        rp.add_argument('password', required=True)
        args = rp.parse_args()
        username = args.username  # 用户
        password = args.password  # 密码

        user = User.query.filter(User.username==username).first()
        if user:
            #验证密码是否正确
            if user.check_password(password):
                #用户登录成功之后 生成一个token 以便于后面去认证token
                token = generate_tokens(user.id)
                current_app.logger.info(token)
                current_app.logger.info('测试验证token',verity_tokens(token))

                return {'token':token}

        return {'message':'用户名或者密码错误','code':20001}

class loginOut(Resource):
    '''
    退出登录
    '''
    #使用了登录拦截的装饰器
    method_decorators = [login_required]
    def post(self):
        if g.user_id:
            g.user_id=None
        return {'msg':'成功退出登录'}

class UserAvatar(Resource):
    '''
    管理用户的头像
    '''
    method_decorators = [login_required]
    def post(self):
        '''
        上传用户头像图片
        :return:
        '''
        #用户 上传的图片数据
        img_data = request.files['file']
        id = g.user_id
        user = User.query.filter(User.id == id).first()

        #设置用户头像保存的路径
        img_dir = current_app.config['AVATAR_DIR']

        #设置图像文件的名字
        img_name  = str(id)+'_'+img_data.filename
        file_path = img_dir+'/'+img_name
        #保存文件
        img_data.save(file_path)
        #在数据库中保存用户头像图片的文件名
        if user:
            user.avatar = img_name
            db.session.commit()
            return {'msg':'上传头像图片成功','avatar':img_name}

class RegisterUser(Resource):
    '''
    用户的注册
    '''
    def post(self):
        rp = RequestParser()
        rp.add_argument('phone',required=True)
        rp.add_argument('username',required=True)
        rp.add_argument('password',required=True)
        rp.add_argument('code',required=True)
        rp.add_argument('invite_code')
        args = rp.parse_args()
        username = args.username
        phone = args.phone
        password = args.password
        code = args.code
        invite_code=args.invite_code
        #验证用户名是否唯一
        u = User.query.filter(User.username==username).first()
        if u:#用户名存在
            current_app.logger.info("{}用户名已经存在，请更换用户名".format(username))
            return {'message':'用户名重复','code':20001}
        #
        real_code=fr.get('registerCode:{}'.format(phone))
        if not real_code or real_code.decode() != code: #数据库中没有code 或者存储的code和参数不一致
            current_app.logger.info('验证错误或者时效')
            return {'message':'验证码错误或者时效','code':20001}

        # 把用户保存到mysql数据库中
        u = User(username=username, phone=phone, pwd=password)

        #验证和关联邀请码
        if invite_code:
            self.check_invite(u,invite_code)




        try:
            #需要用到数据库事物处理
            db.session.add(u)
            db.session.flush()#把数据插入到数据库的缓冲区（得到一个自增的id）并不是插入到数据库中
            account = Account(userId = u.id)
            db.session.add(account)
            db.session.commit()
            return {'msg':'success'}
        except Exception  as ex:
            current_app.logger.error(ex)
            db.session.rollback()
            return {'message':'用户注册时，插入数据库失败','code':20001}
    #验证和关联邀请码
    def check_invite(self,user,invite_code):
        code = invite_code.strip()
        invite_user = User.query.filter(User.inviteId==code).first()
        if invite_user:
            user.invite_user_id=invite_user.id #如果邀请码有效 则把这两个用户关联一下
            invite_user.accountInfo.discount += constants.INVITE_MONEY #邀请用户的账户 增加50元的代金卷
            invite_user.sumFriends += 1 #邀请的记录数+1
class IsExistPhone(Resource):
    '''
    判读手机号 是否存在
    '''
    def post(self):
        phone = request.json.get('phone')
        user = User.query.filter(User.phone == phone).first()

        if user:
            return {'message':'此手机号已经注册过,请更换手机号码','code':20001}
        return {'msg':'success'}


class Smscode(Resource):
    '''
    发送手机短信 验证手机号
    '''
    def get(self): #get 请求 参数往往是 参数名 + 参数
        phone = request.args['phone'].strip()
        #生成一个随机的验证码
        import random
        code = random.randint(1000,9999)
        result = send_code(phone,str(code))
        re_dict = json.loads(result)
        if re_dict['msg']=='提交成功':
            current_app.logger.info('{}发送短信成功'.format(phone))
            #验证码 需要存起来 存放到redis数据库  还需要把验证码在注册的请求中 去验证

            fr.setex('registerCode:{}'.format(phone),constants.SMS_CODE_EXPIRES,code)
            return {'msg':'sucess','smsCode':code}
        else:
            return {'message': '此手机号{}发送短信失败'.format(phone), 'code': 20002}
